package com.jld.spring.service.impl;

import com.jld.spring.mapper.BookMapper;
import com.jld.spring.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service
public class BookServiceImpl implements BookService {
    @Autowired
    private BookMapper bookMapper;

    /**
     * 可以通过@Transactional中的propagation属性设置事务传播行为
     * 修改BookServiceImpl中buyBook()上，注解@Transactional的propagation属性
     * @Transactional(propagation = Propagation.REQUIRED)，默认情况，表示如果当前线程上有已经开
     * 启的事务可用，那么就在这个事务中运行。经过观察，购买图书的方法buyBook()在checkout()中被调
     * 用，checkout()上有事务注解，因此在此事务中执行。所购买的两本图书的价格为80和50，而用户的余
     * 额为100，因此在购买第二本图书时余额不足失败，导致整个checkout()回滚，即只要有一本书买不
     * 了，就都买不了
     * @Transactional(propagation = Propagation.REQUIRES_NEW)，表示不管当前线程上是否有已经开启
     * 的事务，都要开启新事务。同样的场景，每次购买图书都是在buyBook()的事务中执行，因此第一本图
     * 书购买成功，事务结束，第二本图书购买失败，只在第二次的buyBook()中回滚，购买第一本图书不受
     * 影响，即能买几本就买几本
     * @param userId
     * @param bookId
     */
    @Override
    @Transactional(
            //readOnly = true
            //timeout = 3
            //noRollbackFor = ArithmeticException.class
            //noRollbackForClassName = "java.lang.ArithmeticException"
            //isolation = Isolation.DEFAULT
            propagation = Propagation.REQUIRES_NEW //事务的传播行为--->可以只买一本书，不进行结账的事务回滚
    )
    public void buyBook(Integer userId, Integer bookId) {
        //查询图书价格
        Integer price = bookMapper.getPriceByBookId(bookId);
        //更新图书库存
        bookMapper.updateStock(bookId);
        //更新用户的余额
        bookMapper.updateBalance(userId,price);
    }
}
